package br.com.iswe.gerador.ant;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.loader.AntClassLoader2;
import org.apache.tools.ant.taskdefs.Ant.Reference;
import org.apache.tools.ant.util.ClasspathUtils;
import org.apache.velocity.app.Velocity;

import br.com.iswe.gerador.velocity.gerador.GeradorBO;
import br.com.iswe.gerador.velocity.gerador.GeradorConfigFiles;
import br.com.iswe.gerador.velocity.gerador.GeradorDAO;
import br.com.iswe.gerador.velocity.gerador.GeradorJSP;
import br.com.iswe.gerador.velocity.gerador.GeradorTestCases;
import br.com.iswe.gerador.velocity.gerador.GeradorWBean;
import br.com.iswe.gerador.velocity.info.InfoGerador;
import br.com.iswe.gerador.velocity.manager.GeradorEntidadeManager;

@SuppressWarnings("unchecked")
public class ISWEGeradorTask extends Task{
	
	private String teste;
	
	//LIsta das entidade configuradas
	private Vector<Entidade> entidades = new Vector<Entidade>();
	
	private String classpathref = null;
	private ClassLoader classLoader = null;
	
	public void addEntidade(Entidade entidade){
		entidades.add(entidade);
		//Repassar a instancia da task do gerador para as entidades aninhadas.
		entidade.setGeradorTask(this);
	}
	
	
	@Override
	public void execute() throws BuildException {
		try{
			Reference reference = new Reference();
			reference.setProject(getProject());
			reference.setRefId("gerador.classpath");
			classLoader = ClasspathUtils.getClassLoaderForPath(getProject(), reference);
			
			if(classLoader == null){
				System.out.println("AntClassLoader nao encontrado utilizando contextClassLoader");
				classLoader = Thread.currentThread().getContextClassLoader();
			}
			else{
				AntClassLoader2 loader2 = (AntClassLoader2)classLoader;
				System.out.println("Utilizando AntClassLoader2 : ClassPath : " + loader2.getClasspath());
			}
			//Obtem as classes de entidades q seram utilizadas pelo gerador
			List<Class> classes = new ArrayList<Class>();
			for (Entidade ent : entidades) {
				classes.addAll(ent.getClasses());
			}
			if(classes.size() == 0){
				throw new BuildException("Nenhuma classe de entidade foi encontrada !");
			}
			
			//Carrega as propriedade no gerador.
			InfoGerador info = new InfoGerador(getProject().getProperties());
			info.setRunnerClassLoader(getClassLoader());
			
			// Propriedades do Velocity
			Properties velocityProps = new Properties();
			String pathsVelocity = "";
			//Varre as pastas para configurar o velocity
			File pastaRaiz = new File( info.getPropriedade("velocity.file.resource.loader.root.path") );
			if(pastaRaiz.exists() && pastaRaiz.isDirectory()){
				File [] subPastas = pastaRaiz.listFiles();
				for (File sub : subPastas) {
					if(sub.isDirectory()){
						pathsVelocity += sub.getPath() + ",";
					}
				}
			}
			if(info.getPropriedade(GeradorEntidadeManager.VELOCITY_FILE_RESOURCE_LOADER_PATH) != null && !"".equals(info.getPropriedade(GeradorEntidadeManager.VELOCITY_FILE_RESOURCE_LOADER_PATH))){
				pathsVelocity += info.getPropriedade(GeradorEntidadeManager.VELOCITY_FILE_RESOURCE_LOADER_PATH) + ",";
			}
			//Remove a ultima virgula se existir
			if(pathsVelocity.length() > 0){
				pathsVelocity = pathsVelocity.substring(0, pathsVelocity.length()-1);
				velocityProps.setProperty(GeradorEntidadeManager.FILE_RESOURCE_LOADER_PATH, pathsVelocity);
			}
			
			velocityProps.setProperty(GeradorEntidadeManager.FILE_RESOURCE_LOADER_CACHE, info.getPropriedade(GeradorEntidadeManager.VELOCITY_FILE_RESOURCE_LOADER_CACHE));
			Velocity.init(velocityProps);
	
			// Registrar os geradores
			info.addGerador(GeradorDAO.NOME_GERADOR);
			info.addGerador(GeradorBO.NOME_GERADOR);
			info.addGerador(GeradorTestCases.NOME_GERADOR);
			info.addGerador(GeradorWBean.NOME_GERADOR);
			info.addGerador(GeradorJSP.NOME_GERADOR);
			new GeradorEntidadeManager().gerarUmParaUm(classes.toArray(new Class[]{}), classes.toArray(new Class[]{}), info);
	
			// Registrar os geradores
			info.removerGeradores();
			info.addGerador(GeradorConfigFiles.NOME_GERADOR);
			new GeradorEntidadeManager().gerarNParaUm(classes.toArray(new Class[]{}), classes.toArray(new Class[]{}), info);
		}
		catch(Exception exp){
			exp.printStackTrace();
			throw new BuildException("Problemas na geracao : " + exp.getMessage(), exp);
		}
	}

	public String getTeste() {
		return teste;
	}

	public void setTeste(String teste) {
		this.teste = teste;
	}

	public Vector<Entidade> getEntidades() {
		return entidades;
	}

	public void setEntidades(Vector<Entidade> entidades) {
		this.entidades = entidades;
	}

	public String getClasspathref() {
		return classpathref;
	}

	public void setClasspathref(String classpathref) {
		this.classpathref = classpathref;
	}

	public ClassLoader getClassLoader() {
		return classLoader;
	}

	public void setClassLoader(ClassLoader classLoader) {
		this.classLoader = classLoader;
	}
	
	

}
